#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <math.h>
#include "GPUFramework.h"

#pragma comment( lib,"cv.lib" )
#pragma comment( lib,"highgui.lib" )
#pragma comment( lib,"cxcore.lib" )
#pragma comment( lib,"CalGpu.lib" )

int N;
int texSizeX,texSizeY;
GLuint readID,writeID,infoID;
GLuint fb;
GLuint glutWindowHandle;

CGcontext cgContext;
CGprofile fragmentProfile;
CGprogram fragmentProgram;
CGparameter cgData,cgInfo;

float* data;
float *info;
float* result;
FILE *f;
texInfo tex;
int imgw,imgh,imgx,imgy,len;

void display()
{


	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glDrawPixels(imgw,imgh,GL_RGB,GL_FLOAT,result);

	glutSwapBuffers();

}

int main(int argc, char **argv)
{
	int index;
	
	tex.target=GL_TEXTURE_RECTANGLE_ARB;
	tex.internalFormat=GL_RGB32F_ARB;
	tex.format=GL_RGB;

	f=fopen("exchangedata0.txt","r");

	if (f==NULL)
	{
		printf("error");
		return -1;
	}

	
	float a,b;

	fscanf(f,"%d,%d,%d,%d\n",&imgx,&imgy,&imgw,&imgh);

	len=imgw;

	imgw=621;
	imgh=437;

	int n=imgw*imgh;

	info=new float[n*3]();

	int ta,tb;

	for (int i=0;i<n;i++)
	{
		info[i*3]=-1;
		info[i*3+1]=0;
		info[i*3+2]=0;
	}


	for (int i=0;i<imgh;i++)
	{
		for (int j=0;j<imgw;j++)
		{
			fscanf(f,"%d,%f,%f\n",&index,&a,&b);

			ta=(int)a;
			tb=(int)b;

			info[index*3]=index;
			info[index*3+1]=ta;
			info[index*3+2]=tb;

		}

	}

	IplImage *pImage=cvLoadImage("tifa1.jpg",CV_LOAD_IMAGE_COLOR);
	IplImage *pimg=cvCreateImage(cvSize(imgw,imgh),8,3);

	if (pImage->nChannels!=3||pImage->depth!=IPL_DEPTH_8U||pImage->dataOrder!=0)
	{
		return -1;
	}

	int istep=pImage->widthStep;
	int iheight=pImage->height;
	int iwidth=pImage->width;
	unsigned char *sdata=(unsigned char*)pImage->imageData;



	N = imgw*imgh*3;	
	texSizeX=imgw;
	texSizeY=imgh;
	data = new float[iheight*iwidth*3];
	result = new float[N];

	for (int i=0; i<iheight*iwidth*3; i++) {
		data[i] = sdata[i];
	}


	glutWindowHandle=glInitial(&argc,argv);	


	createFBO(&fb);	


	configureCullingSpace(texSizeX,texSizeY);
	

	createTexture(&readID,iwidth,iheight,&tex);
	sendTexture(iwidth,iheight,&tex,data);

	createTexture(&infoID,texSizeX,texSizeY,&tex);
	sendTexture(texSizeX,texSizeY,&tex,info);

	createTexture(&writeID,texSizeX,texSizeY,&tex);


	cgInitial(&cgContext,&fragmentProfile,&fragmentProgram,"GP_F.cg");

	cgParamInitial(&cgData,"textureY",&fragmentProgram);
	cgParamInitial(&cgInfo,"textureInfo",&fragmentProgram);


	bufferInitial(&writeID,&tex,&fragmentProfile,&fragmentProgram);

	cgTexParamConfigure(&readID,&cgData);
	cgTexParamConfigure(&infoID,&cgInfo);


	triggerGPUComputation(texSizeX,texSizeY);


	readBuffer(texSizeX,texSizeY,&tex,result);


	cgRelease(&cgContext,&fragmentProgram);
	FBORelease(&fb);
	textureRelease(&readID);
	textureRelease(&writeID);
	textureRelease(&infoID);
	glRelease(&glutWindowHandle);





	for (int i=0; i<N; i++)
		result[i]=result[i]/255.0;

	glutInit ( &argc, argv );
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(imgw, imgh);
	glutWindowHandle = glutCreateWindow("GPGPU");
	glutDisplayFunc(display);

	glutMainLoop();

	delete [] result;
	delete [] data;

	return 0;
}